<?php

abstract class DBObject {

    protected $table;
    protected static $table_static;

    public $_id = NULL;
    public $_name = NULL;

    public $_changed = NULL;
    public $_loaded = NULL;
    public $_exists = NULL;

    protected $dbo = NULL;

    public function __construct() {

        $this->dbo  = &DBO::getInstance();
    }

    public function __set($name, $value) {

        if($this->$name != $value && $name != 'changed')
            $this->changed = true;

        $name = "_$name";

        $this->$name = $value;
    }

    public function __get($name) {

        if($name == 'exists' && is_null($this->exists)) {

            $res = $this->dbo->getOne("SELECT COUNT(*)
                FROM $this->table
                WHERE name = ?",
                array(
                    DBBString::create($name)
                ));

            throwOnError($res);

            $this->exists = (boolean)($res > 0);
        }

        $name = "_$name";
        return $this->$name;
    }

    public function save($class) {

        if(is_null($this->id)) {

            // TODO: uncomment in PHP 5.3
            //$new_id = $this->dbo->nextId($class::sequence_static);
            eval("\$new_id = \$this->dbo->nextId($class::sequence_static);");

            // TODO: uncomment in PHP 5.3
            //$table_name = $class::table_static;
            eval("\$table_name = $class::table_static;");
            $res = $this->dbo->query("INSERT INTO $table_name
                (id, name) VALUES (?, ?)",
                array(
                    DBInteger::create($new_id),
                    DBString::create($this->name)
                ));

            throwOnError($res);

            $this->id = $new_id;
            $this->loaded = true;
        }

        $this->changed = false;
    }
    
    public function delete() {

        if(!is_null($this->id)) {

            $res = $this->dbo->query("DELETE FROM
                $this->table WHERE id = ?",
                array(
                    DBInteger::create($this->id)
                ));

            throwOnError($res);

            return true;
        }

        return false;
    }

    public function load() {

        $this->loaded = true;
        $this->changed = false;
    }

    public function loadByName() {

        $this->loaded = true;
        $this->changed = false;
    }

    public static function getById($id, $class) {

        $self = new $class;
        $self->id = $id;
        $self->load();
        return $self;
    }

    public static function getByName($name, $class) {

        $self = new $class;
        $self->name = $name;
        $self->loadByName();
        return $self;
    }

    public static function create($name, $class) {

        $self = new $class;
        $self->name = $name;
        $self->save();
        return $self;
    }

    public static function exists($name, $class) {

        $dbo = DBO::getInstance();
        // TODO: uncomment in PHP 5.3
        //$table_name = $class::table_static;
        eval("\$table_name = $class::table_static;");
        $res = $dbo->getOne("SELECT COUNT(*)
            FROM $table_name
            WHERE LOWER(name) = LOWER(?)",
            array(
                DBString::create($name)
            ));

        throwOnError($res);

        return (boolean)($res > 0);
    }

}